package com.eliza.base.views.learn.graphics

import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.OvalShape
import android.os.Build
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableFloatState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.DrawModifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.graphics.drawscope.clipPath
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.drawscope.inset
import androidx.compose.ui.graphics.drawscope.rotate
import androidx.compose.ui.graphics.drawscope.scale
import androidx.compose.ui.graphics.drawscope.translate
import androidx.compose.ui.graphics.drawscope.withTransform
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.res.imageResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.unit.toSize
import com.eliza.base.R

// 图形 绘制自定义内容
object DrawX {
    @Composable
    fun Show() {
        var swi by remember {
            mutableIntStateOf(0)
        }
        Column {
            Button(onClick = { swi = (swi + 1) % 8 }) {
                Text(text = "Click TO Change ${swi}")
            }
            when (swi) {
                0 -> canvasX()
                1 -> canvasEX()
                2 -> canvasText()
                3 -> canvasImg()
                4 -> canvasBasic()
                5 -> canvasPath()
                6 -> canvasAccessing()
            }
        }
    }

    //    核心方法是使用修饰符，例如 Modifier.drawWithContent、Modifier.drawBehind 和 Modifier.drawWithCache。


    @Composable
    private fun canvasX() {
        Text(text = "drawRect")
        Canvas(modifier = Modifier.fillMaxSize()) {
            val canvasQuadrantSize = size / 2F
            drawRect(
                color = Color.Gray,
                size = canvasQuadrantSize
            )
        }
    }

    /*
* 坐标系的原点 ([0,0]) 位于绘制区域最左上角的像素处。x 会随着向右移动而增加，y 则会随着向下移动而增加。
* */
//    DrawScope 会提供一些用于更改绘制命令执行位置或方式的转换。
    @Composable
    private fun canvasEX() {
        Canvas(modifier = Modifier.fillMaxSize()) {
            // 对角线
            val canvasWidth = size.width
            val canvasHeight = size.height
            drawLine(
                strokeWidth = 10f,
                start = Offset(x = canvasWidth, y = 0f),
                end = Offset(x = 0f, y = canvasHeight),
                color = Color.Black
            )

            // 缩放
            scale(scaleX = 4f, scaleY = 3f) {
                drawCircle(Color.Gray, radius = 20.dp.toPx())
            }
            // 平移
            translate(left = 100f, top = -300f) {
                drawCircle(Color.Green, radius = 200.dp.toPx())
            }
            // 旋转
            rotate(degrees = 45F) {
                drawRect(
                    color = Color.LightGray,
                    topLeft = Offset(x = size.width / 3F, y = size.height / 3F),
                    size = size / 3F
                )
            }
//            可用于调整当前 DrawScope 的默认参数，相应地更改绘制边界和平移绘制操作
            val canvasQuadrantSize = size / 2F
            inset(horizontal = 50f, vertical = 30f) {
                drawRect(color = Color.Magenta, size = canvasQuadrantSize)
            }
            //如需对绘制操作应用多个转换，请使用 DrawScope.withTransform() 函数，该函数会创建和应用单个转换来合并您需要的所有更改
            withTransform({
                translate(left = size.width / 5F)
                rotate(degrees = 45F)
            }) {
                drawRect(
                    color = Color.Yellow,
                    topLeft = Offset(x = size.width / 3F, y = size.height / 3F),
                    size = size / 3F
                )
            }
        }
    }

    @Composable
    private fun canvasText() {
        Column {
            val textMeasurer = rememberTextMeasurer()
            Text(text = "drawText")
            Canvas(modifier = Modifier.fillMaxSize()) {
                drawText(textMeasurer, "Hello")
            }
            // TextMeasurer 来获取根据上述因素测量的文本大小
            // 如果您想在文本后面绘制背景，可以通过测量的信息获知文本所占区域的大小：
            val ssss: @Composable (scaleIn: Float, scaleOut: Float) -> Unit = { scaleIn, scaleOut ->
                Spacer(
                    modifier = Modifier
                        // Modifier.drawWithCache，因为绘制文本是一项成本较高的操作。
                        // 在绘制区域的大小发生变化之前，使用 drawWithCache 将有助于缓存创建的对象
                        .drawWithCache {
                            val measuredText =
                                textMeasurer.measure(
                                    AnnotatedString("longText".repeat(10)),
                                    constraints = Constraints.fixedWidth((size.width * scaleIn / scaleOut).toInt()),
                                    style = TextStyle(fontSize = 18.sp)
                                )
                            onDrawBehind {
                                drawRect(Color.Black, size = measuredText.size.toSize())
                                drawText(measuredText)
                            }
                        }
                        .fillMaxSize()
                )
            }
            Column {
                ssss(2f, 3f)
                ssss(1f, 3f)
            }
        }
//        scaleIn: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float

    }

    @Composable
    private fun canvasImg() {
        Text(text = "Canvas draw imageResource")
        val draw = @Composable() {
            //ImageBitmap.imageResource() 加载图片，然后调用 drawImage：
            val dogImage = ImageBitmap.imageResource(id = R.drawable.ic_launcher)
            Canvas(modifier = Modifier.fillMaxSize(), onDraw = {
                drawImage(dogImage)
            })
        }
        Column {
            draw()
        }
    }

    @Composable
    private fun canvasBasic() {
        val draw: @Composable (onDraw: DrawScope.() -> Unit) -> Unit = {
            Canvas(
                modifier = Modifier
                    .size(100.dp)
                    .padding(10.dp),
                onDraw = it
            )
        }
        val purpleColor = Color(0xFFBA68C8)
        Text(text = "Canvas draw basic")
        Column {
            draw() {
                drawCircle(purpleColor)
            }
            draw() {
                drawRect(purpleColor)
            }
            draw() {
                drawRoundRect(purpleColor)
            }
            draw() {
                drawLine(
                    Color.Black,
                    start = Offset(x = 100f, y = 0f),
                    end = Offset(x = 0f, y = 200f)
                )
            }
        }


    }

    @Composable
    private fun canvasPath() {
        Text(text = "Canvas draw path")

        val draw = @Composable() {
            //DrawScope 可以使用 DrawScope.drawPath() 方法绘制路径。
            Spacer(
                modifier = Modifier
                    .drawWithCache {
                        val path = Path()
                        path.moveTo(0f, 0f)
                        path.lineTo(size.width / 2f, size.height / 2f)
                        path.lineTo(size.width, 0f)
                        path.close()
                        onDrawBehind {
                            drawPath(path, Color.Magenta, style = Stroke(width = 10f))
                        }
                    }
                    .fillMaxSize()
            )
        }
        draw()
    }

    @Composable
    private fun canvasAccessing() {
        val draw = @Composable() {
            // 可以使用 DrawScope.drawIntoCanvas() 获取 Canvas 对象本身的访问权限，以调用函数。
            val drawable = ShapeDrawable(OvalShape())
            Spacer(
                modifier = Modifier
                    .drawWithContent {
                        drawIntoCanvas { canvas ->
                            drawable.setBounds(0, 0, size.width.toInt(), size.height.toInt())
                            drawable.draw(canvas.nativeCanvas)
                        }
                    }
                    .fillMaxSize())
        }
        draw()
    }
}

/*
* 基本绘制修饰符为
* drawWithContent，在其中确定可组合项的绘制顺序以及从修饰符内发出的绘制命令。
* drawBehind 是围绕 drawWithContent 的便利封装容器，其绘制顺序设为可组合项内容的后方。
* drawWithCache 会在其内部调用 onDrawBehind 或 onDrawWithContent，并提供一种机制来缓存在其中创建的对象。
* */



object DrawModifiers {
    @Composable
    fun Show() {
        val remember = remember {
            mutableIntStateOf(0)
        }
        Button(onClick = { remember.intValue = (remember.intValue + 1) % 5 }) {
            Text(text = "DrawModifiers ${remember.intValue}")
        }
        when (remember.intValue) {
            0 -> graphicsLayerX()
            1 -> drawBehindX()
            2 -> drawContentX()
            3 -> shapeX()
            4 -> GraphicsLayerX.Show()
        }
    }

    @Composable
    private fun drawContentX() {
        var pointerOffset by remember {
            mutableStateOf(Offset(0f, 0f))
        }
        Column(
            modifier = Modifier
                .fillMaxSize()
                .pointerInput("dragging") {
                    detectDragGestures { change, dragAmount ->
                        pointerOffset += dragAmount
                    }
                }
                .onSizeChanged {
                    pointerOffset = Offset(it.width / 2f, it.height / 2f)
                }
                //可以在可组合项内容之前或之后执行 DrawScope 操作。
                //drawContent 来渲染可组合项的实际内容
                .drawWithContent {
                    drawContent()
                    // draws a fully black area with a small keyhole at pointerOffset that’ll show part of the UI.
                    drawRect(
                        Brush.radialGradient(
                            listOf(Color.Transparent, Color.Black),
                            center = pointerOffset,
                            radius = 100.dp.toPx(),
                        )
                    )
                }
        ) {
            Column {
//                Text(text = "pointerOffset : ${pointerOffset.x} ${pointerOffset.y}")
                Text(text = "aaaaaaaaaa ".repeat(50), color = Color.Magenta)
            }

        }
    }

    @Composable
    private fun drawBehindX() {
        Column {
            Text(
                "Hello Compose!",
                modifier = Modifier
                    .drawBehind {
                        drawRoundRect(
                            Color(0xFFBBAAEE),
                            cornerRadius = CornerRadius(10.dp.toPx())
                        )
                    }
                    .padding(4.dp)
            )
            Text(
                "drawWithCache!",
                //Modifier.drawWithCache 会缓存在其中创建的对象。
                // 只要绘制区域的大小不变，或者读取的任何状态对象都未发生变化，对象就会被缓存。
                modifier = Modifier
                    .drawWithCache {
                        val brush = Brush.linearGradient(
                            listOf(
                                Color(0xFF9E82F0),
                                Color(0xFF42A5F5)
                            )
                        )
                        onDrawBehind {
                            drawRoundRect(
                                brush,
                                cornerRadius = CornerRadius(10.dp.toPx())
                            )
                        }
                    }
            )
        }

    }

    @Composable
    private fun graphicsLayerX() {
        /*
    *
    * Modifier.graphicsLayer 是一个修饰符，用于将可组合项的内容绘制到绘图层。图层提供几项不同的功能
    *   隔离其绘制指令（类似于 RenderNode）。作为图层一部分捕获的绘制指令，可由渲染管道高效地重新发出，而无需重新执行应用代码。
    *    应用于图层中包含的所有绘制指令的转换。
    *    合成功能的光栅化。对图层进行光栅化时，系统会执行其绘制指令，并将输出捕获到屏幕外缓冲区。
    *         为后续帧合成此类缓冲区比执行单个指令更快，但在应用缩放或旋转等转换时，其行为类似于位图。

    Modifier.graphicsLayer 用于隔离其绘制指令；例如，可以使用 Modifier.graphicsLayer 应用各种转换。
    *   您可以为这些转换添加动画或对其进行修改，而无需重新执行绘制 lambda。
    Modifier.graphicsLayer 不会更改可组合项的测量尺寸或位置，因为它只会影响绘制阶段。
    *   这意味着，如果可组合项最终绘制到了其布局边界之外，则可能会与其他对象重叠。
    * */
//    val draw: @Composable (onDraw: DrawScope.() -> Unit)->Unit = {
//    val foo = @Composable { ... }

        val slider: @Composable (
            text: String,
            scale: MutableFloatState,
            valueRange: ClosedFloatingPointRange<Float>
        ) -> Unit = { text, scale, valueRange ->
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(5.dp)
            ) {
                Text(text = "$text : ${scale.floatValue.toString()}")
                Slider(
                    value = scale.floatValue,
                    onValueChange = { scale.floatValue = it },
                    modifier = Modifier
                        .padding(1.dp)
                        .height(2.dp),
                    valueRange = valueRange,
                    steps = 20
                )
            }
        }
        Column {
            val scaleX = remember { mutableFloatStateOf(1f) }
            val scaleY = remember { mutableFloatStateOf(1f) }
            slider("scaleX", scaleX, 0.5f..5f)
            slider("scaleY", scaleY, 0.5f..5f)
            val translationX = remember { mutableFloatStateOf(0f) }
            val translationY = remember { mutableFloatStateOf(0f) }
            slider("translationX", translationX, 0f..100f)
            slider("translationY", translationY, 0f..100f)

            val rotationX = remember { mutableFloatStateOf(0f) }
            val rotationY = remember { mutableFloatStateOf(0f) }
            val rotationZ = remember { mutableFloatStateOf(0f) }

            slider("rotationX", rotationX, 0f..180f)
            slider("rotationY", rotationY, 0f..180f)
            slider("rotationZ", rotationZ, 0f..180f)

            val pivotFractionX = remember { mutableFloatStateOf(0.5f) }
            val pivotFractionY = remember { mutableFloatStateOf(0.5f) }
            slider("pivotFractionX", pivotFractionX, 0f..1f)
            slider("pivotFractionY", pivotFractionY, 0f..1f)

            Column {
                Text(text = "img")
                Image(
                    painter = painterResource(id = R.drawable.ic_launcher),
                    contentDescription = "Sunset",
                    modifier = Modifier
                        .graphicsLayer {
                            //设置原点
                            this.transformOrigin = TransformOrigin(0f, 0f)
                            //缩放
                            this.scaleX = scaleX.floatValue
                            this.scaleY = scaleY.floatValue
                            //平移
                            this.translationX = translationX.floatValue.dp.toPx()
                            this.translationY = translationY.floatValue.dp.toPx()

                            this.rotationX = rotationX.floatValue
                            this.rotationY = rotationY.floatValue
                            this.rotationZ = rotationZ.floatValue
                        }
                        .fillMaxWidth()
                )
            }
        }
    }

    // 图形形状
    @Composable
    private fun shapeX() {
        Column(modifier = Modifier.padding(16.dp)) {
            Text(text = "Modifier.graphicsLayer 与 Modifier.clip ")
            val size = 150.dp
            Box(
                modifier = Modifier
                    .clip(RectangleShape)//内容会保留在原始边界内。
                    .size(size)
                    .border(2.dp, Color.Black)

                    .graphicsLayer {
                        // 裁剪成圆形
                        clip = true
                        shape = CircleShape
                        translationY = 50.dp.toPx()
                        this.alpha = 0.5f
                    }
                    .background(Color(0xFFF06292))
            ) {
                Text(
                    "Hello Compose",
                    style = TextStyle(color = Color.Black, fontSize = 30.sp),
                    modifier = Modifier.align(Alignment.Center)
                )
            }
            Box(
                modifier = Modifier
                    .size(size)
                    .clip(CircleShape)
                    .background(Color(0xFF4DB6AC))
            )
        }
    }
    /*
    * 当 alpha 设为小于 1.0f 时，图层的整个内容都会绘制到屏幕外缓冲区（前提是 CompositingStrategy 未设为 ModulateAlpha）
    * 如需了解详情，请参阅 CompositingStrategy 部分。
    * */

}

object GraphicsLayerX {
    @Composable
    fun Show() {
        val remember = remember {
            mutableIntStateOf(0)
        }
        Button(onClick = { remember.intValue = (remember.intValue + 1) % 6 }) {
            Text(text = "GraphicsLayerX ${remember.intValue}")
        }
        when (remember.intValue) {
            0 -> BlendModesX()
            1 -> BlendModesXx()
            2 -> ModulateAlphaX()
            3 -> CustomizeModifierX()
        }
    }

    /*
    * 可组合项的内容始终会先光栅化为屏幕外纹理或位图，然后再渲染到目标位置。这对于应用 BlendMode 操作来遮盖内容，以及在渲染复杂的绘制指令集时提高性能非常有用。

        BlendModes 就是使用 CompositingStrategy.Offscreen 的一个例子。如下例所示，假设您想通过发出使用 BlendMode.Clear 的绘制命令来移除 Image 可组合项的部分内容。
* 如果您未将 compositingStrategy 设为 CompositingStrategy.Offscreen，BlendMode 会与其下方的所有内容进行交互。
    * */
    @Composable
    private fun BlendModesX() {
        Text(text = "CompositingStrategy.Offscreen 与 BlendMode.Clear")

        Image(painter = painterResource(id = R.drawable.tou_xiang),
            contentDescription = "Dog",
            contentScale = ContentScale.Crop,
            modifier = Modifier
                .size(120.dp)
                .aspectRatio(1f)
                .background(
                    Brush.linearGradient(
                        listOf(
                            Color(0xFFC5E1A5),
                            Color(0xFF80DEEA)
                        )
                    )
                )
                .padding(5.dp)
                .graphicsLayer {
                    //合成策略，画面之外
                    compositingStrategy = CompositingStrategy.Offscreen
                }
                .drawWithCache {
                    val path = Path()
                    path.addOval(
                        Rect(
                            topLeft = Offset.Zero,
                            bottomRight = Offset(size.width, size.height)
                        )
                    )
                    onDrawWithContent {
                        clipPath(path) {
                            // this draws the actual image - if you don't call drawContent, it wont
                            // render anything
                            this@onDrawWithContent.drawContent()
                        }
                        val dotSize = size.width / 7f
                        // Clip a white border for the content
                        drawCircle(
                            Color.Green,
                            radius = dotSize,
                            center = Offset(
                                x = size.width - dotSize,
                                y = size.height - dotSize
                            ),
//                            混合模式
//                            blendMode = BlendMode.Overlay
                            blendMode = BlendMode.Clear
                        )
                        // draw the red circle indication
                        drawCircle(
                            Color(0xFFEF5350), radius = dotSize * 0.8f,
                            center = Offset(
                                x = size.width - dotSize,
                                y = size.height - dotSize
                            )
                        )
                    }

                }
        )
    }

    @Composable
    private fun BlendModesXx() {
        //CompositingStrategy.Auto 与 CompositingStrategy.Offscreen - 屏幕外策略会裁剪至此区域，自动策略则不会
        Text(text = "CompositingStrategy.Auto/Offscreen - 屏幕外策略会裁剪至此区域")
        Column(
            modifier = Modifier
                .fillMaxSize()
                .wrapContentSize(Alignment.Center)
        ) {
            /** Does not clip content even with a graphics layer usage here. By default, graphicsLayer
            does not allocate + rasterize content into a separate layer but instead is used
            for isolation. That is draw invalidations made outside of this graphicsLayer will not
            re-record the drawing instructions in this composable as they have not changed **/
            Canvas(
                modifier = Modifier
                    .graphicsLayer()
                    .size(100.dp) // Note size of 100 dp here
                    .border(2.dp, color = Color.Blue)
            ) {
                // ... and drawing a size of 200 dp here outside the bounds
                drawRect(color = Color.Magenta, size = Size(200.dp.toPx(), 200.dp.toPx()))
            }

            Spacer(modifier = Modifier.size(100.dp))

            /** Clips content as alpha usage here creates an offscreen buffer to rasterize content
            into first then draws to the original destination **/
            Canvas(
                modifier = Modifier
                    // force to an offscreen buffer
                    .graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen)
                    .size(100.dp) // Note size of 100 dp here
                    .border(2.dp, color = Color.Blue)
            ) {
                /** ... and drawing a size of 200 dp. However, because of the CompositingStrategy.Offscreen usage above, the
                content gets clipped **/
                drawRect(color = Color.Red, size = Size(200.dp.toPx(), 200.dp.toPx()))
            }


        }
    }

    /*
    * 此合成策略会调整 graphicsLayer 中记录的每条绘制指令的 alpha 值。除非设置了 RenderEffect，
    * 否则此策略不会针对 1.0f 以下的 alpha 创建屏幕外缓冲区，以便可以更高效地进行 alpha 呈现。
    * 不过，此策略可以针对重叠内容提供不同的结果。
    * 对于事先知道内容不重叠的用例，与 alpha 值小于 1 的 CompositingStrategy.Auto 相比，此策略可以提供更好的性能。
    * */
    val Purple = Color(0xFF7E57C2)
    val Yellow = Color(0xFFFFCA28)
    val Red = Color(0xFFEF5350)

    @Composable
    private fun ModulateAlphaX() {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(32.dp)
                .verticalScroll(rememberScrollState()),
        ) {
            Text(text = "alpha = 1f CompositingStrategy.Auto/OffScreen")

            // Base drawing, no alpha applied
            Canvas(
                modifier = Modifier.size(200.dp)
            ) {
                drawSquares()
            }

            Spacer(modifier = Modifier.size(10.dp))

            // Alpha 0.5f applied to whole composable
            Text(text = "alpha = 0.5f CompositingStrategy.Auto/OffScreen")

            Canvas(modifier = Modifier
                .size(200.dp)
                .graphicsLayer {
                    alpha = 0.5f
                }) {
                drawSquares()
            }
            Spacer(modifier = Modifier.size(10.dp))

            // 0.75f alpha applied to each draw call when using ModulateAlpha
            Text(text = "alpha = 0.75f CompositingStrategy.ModulateAlpha")

            Canvas(modifier = Modifier
                .size(200.dp)
                .graphicsLayer {
                    compositingStrategy = CompositingStrategy.ModulateAlpha
                    alpha = 0.75f
                }) {
                drawSquares()
            }
        }
    }

    private fun DrawScope.drawSquares() {
        val size = Size(100.dp.toPx(), 100.dp.toPx())
        drawRect(color = Red, size = size)
        drawRect(
            color = Purple, size = size,
            topLeft = Offset(size.width / 4f, size.height / 4f)
        )
        drawRect(
            color = Yellow, size = size,
            topLeft = Offset(size.width / 4f * 2f, size.height / 4f * 2f)
        )
    }

    //    TODO
    @Composable
    private fun ModulateBitmapX() {
//         1.7.0-alpha
//        将可组合项的内容写入位图
        val coroutineScope = rememberCoroutineScope()
//        val graphicsLayer = rememberGraphicsLayer()

    }

    class FlippedModifier : DrawModifier {
        override fun ContentDrawScope.draw() {
            scale(1f, -1f) {
                this@draw.drawContent()
            }
        }
    }

    fun Modifier.flipped() = this.then(FlippedModifier())

    @Composable
    fun CustomizeModifierX(modifier: Modifier = Modifier) {
        Text(text = "CustomizeModifierX")
        Text(
            "Hello Compose!",
            modifier = Modifier
                .flipped()
        )
    }
}
